iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Software Development

或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA系列 第 15

[Day15] - Box Drop Project精進計畫(7) - Housekeeping

  • 分享至 

  • xImage
  •  

今天我們來做個housekeeping,整理一下程式。

create_boundary_spc & create_initial_velocity

首先將邊界條件及初始速度,獨立出各自的creator function,放於creators.py中,過程與其它creator function類似,不再贅述。

#creators.py
def create_boundary_spc(fields, deck=None):
    deck = deck or constants.LSDYNA
    type_ = BCType.BOUNDARY_SPC_SET
    return base.CreateEntity(deck, type_, fields)

def create_initial_velocity(fields, deck=None):
    deck = deck or constants.LSDYNA
    type_ = BCType.INITIAL_VELOCITY_SET
    return base.CreateEntity(deck, type_, fields)

Card Handler

接著建立一個card_handlers.py來處理controldatabasecontrol card

get_card_ent

由於ANSA內允許創造多個control card或是databaseEntity,有時會造成一些輸出的困擾,所以我們會希望盡量減少這類Entity的數量。透過_get_card_ent,我們可以回傳第一個由base.CollectEntities所收集到的Entity。如果ANSA環境內沒有該Entity,我們則建立並回傳。

#card_handlers.py
def get_card_ent(type_, deck=None):
    deck = deck or constants.LSDYNA
    ents = base.CollectEntities(deck, None, type_)
    if ents:
        return ents[0]
    return base.CreateEntity(deck, type_)

card_handler

card_handler需要entparamsdeck三個參數。ctrl_params的格式為一list,裡面每個元素為一個含有兩個元素的tupletuple的第一個元素為*CONTROL*DATABASEkeyword後的後綴(不含底線),第二個元素為一dict,內含想設定的參數及其值。這樣的話,我們就可以透過下面的語法來設定controldatabasecontrol card

#*CONTROL_TERMINATION
crtl_ent = get_card_ent(ControlCardType.CONTROL)
ctrl_params = [('TERMINATION', {'ENDTIM': 1.5E-2})]
crtl_ent = card_handler(crtl_ent, ctrl_params)

Day07提到的,這類型Entity最tricky的地方就是必須要先ON,剩下的就是將params內給定的參數提取出來,放入fields內,最後透過set_entity_values一次設定完成。

#card_handlers.py
def card_handler(ent, params, deck=None):
    deck = deck or constants.LSDYNA
    fields = {}
    for keyword, fields_ in params:
        fields[keyword] = 'ON'
        ent.set_entity_values(deck, fields=fields)
        if fields_:
            fields.update({(keyword + '_' + k): v
                           for k, v in fields_.items()})
    ent.set_entity_values(deck, fields=fields)
    return ent

Utils

建立一個utils.py來儲存一些utility function

set_deck_to

set_deck_to為一helper function,可透過此function將當前ANSA deck設為LS-DYNA。

#utils.py
def set_deck_to(deck=None):
    deck = deck or constants.LSDYNA
    base.SetCurrentDeck(deck)

set_zoom_all_view

set_zoom_all_view呼叫base.ZoomAll,僅是方便視角的呈現。

#utils.py
def set_zoom_all_view():
    base.ZoomAll()

set_obj_visible_for_output_deck

set_obj_visible_for_output_deck將需要設定為輸出的contact,邊界條件及初始速度等,打包放入一個函數,方便使用。

#utils.py
def set_obj_visible_for_output_deck(deck=None):
    deck = deck or constants.LSDYNA
    keys = {LSDYNAType.CONTACT,
            BCType.BOUNDARY_SPC_SET,
            BCType.INITIAL_VELOCITY_SET}
    base.SetEntityVisibilityValues(deck, {key.value: 'on' for key in keys})

output_file

將輸出相關設定移至output_file function

#utils.py
def output_file(filename, deck=None):
    deck = deck or constants.LSDYNA
    base_dir = Path(__file__).parent
    file_str = (base_dir / filename).as_posix()
    set_obj_visible_for_output_deck(deck)
    base.OutputLSDyna(filename=file_str)
    base.SetEntityVisibilityValues(deck, {"CONTACT": "off"})
    set_zoom_all_view()
    return file_str

run_dyna

將求解相關設定移至run_dyna function。除了檔名路徑是必要輸入參數外,solver的路徑、想使用的cpu數量、想使用的memory大小及額外控制,都透過short circuit技巧給定了預設值。

#utils.py
def run_dyna(file_str,
             solver_str=None,
             ncpu=None,
             memory=None,
             d=None):
    solver_str = solver_str or f'{Path.home()}/LS-DYNA/13.0/smp-dyna_s'
    i = f'i={file_str}'
    ncpu = f'ncpu={ncpu}' if ncpu is not None else f'ncpu=8'
    memory = f'memory={memory}' if memory is not None else f'memory=1000m'
    d = f'd={d}' if d is not None else f'd=nodump'
    commands = [solver_str, i, ncpu, memory, d]

    subprocess.run(commands)

Code

本日程式碼傳送門


上一篇
[Day14] - Box Drop Project精進計畫(6) - Box
下一篇
[Day16] - Box Drop Project精進計畫(8) - 使用base.ImportV1
系列文
或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言